//
//  NSDateAdditions.m
//  Tint
//
//  Created by Kevin Wu on 2/22/12.
//  Copyright (c) 2012 Telligenty. All rights reserved.
//

#import "NSDateAdditions.h"
#import "TTCore.h"


@implementation NSDate (Tint)


#pragma mark - Creating

+ (NSDate *)dateWithUNIXTimeString:(NSString *)string {
    return [NSDate dateWithTimeIntervalSince1970:[string doubleValue]];
}

+ (NSDate *)dateTomorrow {
    return [[NSDate date] dateByAddingDays:1];
}

+ (NSDate *)dateYesterday {
    return [[NSDate date] dateBySubtractingDays:1];
}

+ (NSDate *)dateWithDaysFromNow:(NSUInteger)days {
    return [[NSDate date] dateByAddingDays:days];
}

+ (NSDate *)dateWithDaysBeforeNow:(NSUInteger)days {
    return [[NSDate date] dateBySubtractingDays:days];
}

+ (NSDate *)dateWithHoursFromNow:(NSUInteger)hours {
    return [[NSDate date] dateByAddingHours:hours];
}

+ (NSDate *)dateWithHoursBeforeNow:(NSUInteger)hours {
    return [[NSDate date] dateBySubtractingHours:hours];
}

+ (NSDate *)dateWithMinutesFromNow:(NSUInteger)minutes {
    return [[NSDate date] dateByAddingMinutes:minutes];
}

+ (NSDate *)dateWithMinutesBeforeNow:(NSUInteger)minutes {
    return [[NSDate date] dateBySubtractingMinutes:minutes];
}

+ (NSDate *)dateWithSecondsFromNow:(NSUInteger)seconds {
    return [[NSDate date] dateByAddingSeconds:seconds];
}

+ (NSDate *)dateWithSecondsBeforeNow:(NSUInteger)seconds {
    return [[NSDate date] dateBySubtractingSeconds:seconds];
}

- (NSDate *)dateAtStartOfDay {
	NSDateComponents *components = [self dateComponents];
	[components setHour:0];
	[components setMinute:0];
	[components setSecond:0];
	return [[NSCalendar currentCalendar] dateFromComponents:components];
}

- (NSDate *)dateAtNoonOfDay {
    NSDateComponents *components = [self dateComponents];
	[components setHour:12];
	[components setMinute:0];
	[components setSecond:0];
	return [[NSCalendar currentCalendar] dateFromComponents:components];
}



#pragma mark - Date components

- (NSDateComponents *)dateComponents {
    NSCalendarUnit calendarUnit = 
    NSEraCalendarUnit | 
    NSYearCalendarUnit | 
    NSMonthCalendarUnit | 
    NSDayCalendarUnit |  
    NSHourCalendarUnit | 
    NSMinuteCalendarUnit | 
    NSSecondCalendarUnit | 
    NSWeekCalendarUnit | 
    NSWeekdayCalendarUnit | 
    NSWeekdayOrdinalCalendarUnit | 
    NSQuarterCalendarUnit | 
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= TTIOS_5_0
    NSWeekOfMonthCalendarUnit | 
    NSWeekOfYearCalendarUnit | 
    NSYearForWeekOfYearCalendarUnit | 
#endif
    NSCalendarCalendarUnit | 
    NSTimeZoneCalendarUnit;
    return [[NSCalendar currentCalendar] components:calendarUnit fromDate:self];
}



#pragma mark - Adjusting

- (NSDate *)dateByAddingDays:(NSUInteger)days {
	NSTimeInterval timeInterval = [self timeIntervalSinceReferenceDate] + TTTimeIntervalDay() * days;
	return [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
}

- (NSDate *)dateBySubtractingDays:(NSUInteger)days {
    NSTimeInterval timeInterval = [self timeIntervalSinceReferenceDate] - TTTimeIntervalDay() * days;
	return [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
}


- (NSDate *)dateByAddingHours:(NSUInteger)hours {
	NSTimeInterval timeInterval = [self timeIntervalSinceReferenceDate] + TTTimeIntervalHour() * hours;
	return [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
}

- (NSDate *)dateBySubtractingHours:(NSUInteger)hours {
	NSTimeInterval timeInterval = [self timeIntervalSinceReferenceDate] - TTTimeIntervalHour() * hours;
	return [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
}


- (NSDate *)dateByAddingMinutes:(NSUInteger)minutes {
	NSTimeInterval timeInterval = [self timeIntervalSinceReferenceDate] + TTTimeIntervalMinute() * minutes;
	return [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
}

- (NSDate *)dateBySubtractingMinutes:(NSUInteger)minutes {
	NSTimeInterval timeInterval = [self timeIntervalSinceReferenceDate] - TTTimeIntervalMinute() * minutes;
	return [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
}


- (NSDate *)dateByAddingSeconds:(NSUInteger)seconds {
    NSTimeInterval timeInterval = [self timeIntervalSinceReferenceDate] + seconds;
	return [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
}

- (NSDate *)dateBySubtractingSeconds:(NSUInteger)seconds {
    NSTimeInterval timeInterval = [self timeIntervalSinceReferenceDate] - seconds;
	return [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
}



#pragma mark - Comparing

- (BOOL)isEarlierThanDate:(NSDate *)dt {
	return ([self earlierDate:dt] == self);
}

- (BOOL)isLaterThanDate:(NSDate *)dt {
	return ([self laterDate:dt] == self);
}


- (BOOL)isSameYearAsDate:(NSDate *)dt {
    NSDateComponents *components1 = [self dateComponents];
    NSDateComponents *components2 = [dt dateComponents];
	return ([components1 year] == [components2 year]);
}

- (BOOL)isSameMonthAsDate:(NSDate *)dt {
    NSDateComponents *components1 = [self dateComponents];
    NSDateComponents *components2 = [dt dateComponents];
	return (([components1 year] == [components2 year]) &&
			([components1 month] == [components2 month]));
}

- (BOOL)isSameDayAsDate:(NSDate *)dt {
    NSDateComponents *components1 = [self dateComponents];
    NSDateComponents *components2 = [dt dateComponents];
	return (([components1 year] == [components2 year]) &&
			([components1 month] == [components2 month]) && 
			([components1 day] == [components2 day]));
}

// This hard codes the assumption that a week is 7 days
- (BOOL)isSameWeekAsDate:(NSDate *)dt {
    NSDateComponents *components1 = [self dateComponents];
    NSDateComponents *components2 = [dt dateComponents];
	
	// Must be same week. 12/31 and 1/1 will both be week "1" if they are 
    // in the same week
	if ([components1 week] != [components2 week]) return NO;
	
	// Must have a time interval under 1 week. Thanks @aclark
	return (abs([self timeIntervalSinceDate:dt]) < TTTimeIntervalWeek());
}




#pragma mark - Intervals

- (NSInteger)daysSinceDate:(NSDate *)dt {
	NSTimeInterval timeInterval = [self timeIntervalSinceDate:dt];
	return (NSInteger)(timeInterval / TTTimeIntervalDay());
}

- (NSInteger)hoursSinceDate:(NSDate *)dt {
	NSTimeInterval timeInterval = [self timeIntervalSinceDate:dt];
	return (NSInteger)(timeInterval / TTTimeIntervalHour());
}

- (NSInteger)minutesSinceDate:(NSDate *)dt {
	NSTimeInterval timeInterval = [self timeIntervalSinceDate:dt];
	return (NSInteger)(timeInterval / TTTimeIntervalMinute());
}

- (NSInteger)secondsSinceDate:(NSDate *)dt {
    return (NSInteger)[self timeIntervalSinceDate:dt];
}

@end
